namespace SPDeploy.Library
{
    using System;
    using System.IO;
    using System.Reflection;
    using System.Xml;
    using System.Xml.Schema;
    using Data;
    using Exceptions;
    using Helpers;
    using Interfaces;

    public class DeploymentConfigXmlLoader : IDeploymentConfigLoader
    {
        #region IDeploymentConfigLoader Members

        public Deployment Load(Stream stream)
        {
            var doc = new XmlDocument();
            doc.Load(stream);

            try
            {
                ValidateXml(doc);
            }
            catch (XmlSchemaException e)
            {
                throw new ValidationException(string.Format("Validation error at {0}, {1}: {2} ", e.LineNumber, e.LinePosition, e.Message));
            }

            var deployment = XmlDeserializer.Deserialize<Deployment>(doc.InnerXml);
            return deployment;
        }

        public bool TryValidate(Stream stream)
        {
            try
            {
                Load(stream);
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        #endregion

        #region Methods: private

        private static Stream GetAttachedSchemaStream()
        {
            return Assembly.GetExecutingAssembly().GetManifestResourceStream(Settings.Default.MainSchemaResource);
        }

        private static void ValidateXml(XmlNode doc)
        {
            var nodeReader = new XmlNodeReader(doc);
            var settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.Schema;
            settings.Schemas.Add(null, XmlReader.Create(GetAttachedSchemaStream()));
            XmlReader reader = XmlReader.Create(nodeReader, settings);
            while (reader.Read())
            {
            }
        }

        #endregion
    }
}